package com.quan.mall.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.quan.commons.core.biz.support.MyBaseServiceImpl;
import com.quan.commons.core.utils.PageUtils;
import com.quan.commons.core.utils.RedisUtils;
import com.quan.mall.service.PmsCategoryBrandRelationService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.quan.mall.commons.vo.PmsCategoryVo;
import com.quan.mall.entity.PmsCategory;
import com.quan.mall.mapper.PmsCategoryMapper;
import com.quan.mall.service.PmsCategoryService;
import org.springframework.transaction.annotation.Transactional;


@Slf4j
@Service
public class PmsCategoryServiceImpl extends MyBaseServiceImpl<PmsCategoryMapper, PmsCategory> implements PmsCategoryService {

    @Autowired
	private PmsCategoryMapper mapper;

    @Autowired
    private PmsCategoryBrandRelationService pmsCategoryBrandRelationService;

    @Autowired
    private RedisUtils redisUtils;

	@Override
    public List<PmsCategoryVo> queryList(PageUtils pageUtils, PmsCategoryVo vo) {
        QueryWrapper<PmsCategory> queryWrapper = new QueryWrapper<PmsCategory>(vo);

        List<PmsCategory> list = super.list(pageUtils, queryWrapper);
        List<PmsCategoryVo> collect = list.stream().map(item -> {
            PmsCategoryVo bean = new PmsCategoryVo();
            BeanUtils.copyProperties(item, bean);
            return bean;
        }).collect(Collectors.toList());

        return collect;
    }

    @Override
    public PageUtils queryPage(PageUtils pageUtils, PmsCategoryVo vo) {
        QueryWrapper<PmsCategory> queryWrapper = new QueryWrapper<PmsCategory>(vo);

        if(StringUtils.isNotBlank(vo.getKeyword())) {
            queryWrapper.and(w -> {
                w.like("username", vo.getKeyword());
            });
        }

        final IPage<PmsCategory> page = super.selectPage(pageUtils, queryWrapper);

        PageUtils ps = new PageUtils(page);

        final List<PmsCategory> records = page.getRecords();

        final List<PmsCategory> collect = records.stream().map((item) -> {
            PmsCategoryVo bean = new PmsCategoryVo();
            BeanUtils.copyProperties(item, bean);
            return bean;
        }).collect(Collectors.toList());

        ps.setRecords(collect);
        return ps;
    }

    @Override
    public List<PmsCategoryVo> listWithTree() {

        //String cateJSON = this.redisUtils.get("mall:category");


        //if(StringUtils.isBlank(cateJSON)) {

            final List<PmsCategory> list = super.list();

            // 获取一级分类
            final List<PmsCategoryVo> categorys = list.stream()
                    //.filter(category -> category.getPid() == 0)
                    .filter(category -> category.getPid() == 0)
                    .map(item -> {
                        PmsCategoryVo vo = new PmsCategoryVo();
                        BeanUtils.copyProperties(item, vo);
                        // 获取子分类
                        vo.setChildren(getChildrens(vo, list));
                        return vo;
                    }).sorted((menu, menu2) -> {
                        //2、菜单的排序
                        return (menu.getSort() == null ? 0 : menu.getSort()) - (menu2.getSort() == null ? 0 : menu2.getSort());
                    }).collect(Collectors.toList());

            //cateJSON = JSON.toJSONString(categorys);
            //this.redisUtils.set("mall:category", JSON.toJSONString(categorys));
        //}

        //final List<PmsCategoryVo> pmsCategoryVos = JSON.parseArray(cateJSON, PmsCategoryVo.class);
        return categorys;
    }

    //递归查找所有菜单的子菜单
    private List<PmsCategory> getChildrens(PmsCategoryVo root, List<PmsCategory> all) {

        List<PmsCategory> children = all.stream().filter(categoryEntity -> {
            return categoryEntity.getPid().equals(root.getId());
        }).map(categoryEntity -> {
            PmsCategoryVo vo = new PmsCategoryVo();
            BeanUtils.copyProperties(categoryEntity, vo);
            //1、找到子菜单(递归)
            vo.setChildren(getChildrens(vo, all));
            return vo;
        }).sorted((menu, menu2) -> {
            //2、菜单的排序
            return (menu.getSort() == null ? 0 : menu.getSort()) - (menu2.getSort() == null ? 0 : menu2.getSort());
        }).collect(Collectors.toList());

        return children;

    }

    @Override
    public IPage<PmsCategory> selectPage(PageUtils pageUtils, PmsCategory entity) {
        QueryWrapper<PmsCategory> queryWrapper = new QueryWrapper<PmsCategory>(entity);
        return super.selectPage(pageUtils, queryWrapper);
    }

    @Override
    public Long[] findCategoryPath(Long categoryId) {

        List<Long> paths = new ArrayList<>();

        //递归查询是否还有父节点
        List<Long> parentPath = findParentPath(categoryId, paths);

        //进行一个逆序排列
        Collections.reverse(parentPath);

        return (Long[]) parentPath.toArray(new Long[parentPath.size()]);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateCascade(PmsCategory category) {

        super.updateById(category);

//        this.pmsCategoryBrandRelationService.updateCategory(category.getId(), category.getName());
    }

    private List<Long> findParentPath(Long categoryId, List<Long> paths) {
        //1、收集当前节点id
        paths.add(categoryId);

        //根据当前分类id查询信息
        PmsCategory byId = this.getById(categoryId);
        //如果当前不是父分类
        if (byId.getPid() != 0) {
            findParentPath(byId.getPid(), paths);
        }
        return paths;
    }

}